Skip to content

feat(ooxml.js): associate a docx Caption paragraph with the figure it describes - #1201

Merged
Mearman merged 1 commit into
mainfrom
feat/docx-figure-captions
Sep 10, 2026
Merged

feat(ooxml.js): associate a docx Caption paragraph with the figure it describes#1201
Mearman merged 1 commit into
mainfrom
feat/docx-figure-captions

Conversation

@fcbwilliams

Copy link
Copy Markdown
Member

… describes

A figure's caption is usually the most informative text about it in the
whole document -- more so than alt text, and unlike alt text it is
usually actually present. The reader already surfaces the figure and
the caption paragraph, but nothing connects them, so a consumer holding
a `ContentImageBlock` has no way to know which of the surrounding
paragraphs describes it.

`associateFigureCaptions` records it on the image block's new optional
`caption`, matching a `Caption`-styled paragraph -- what Word's Insert
Caption produces -- case-insensitively, since `styleId` is documented as
a producer's own spelling.

**Associated, never moved or copied.** The caption paragraph stays
exactly where it is: it is real prose the document contains, so removing
it would lose text a reader expects to find, and copying it into the
image would make every flat-text projection carry it twice. What the
image gains is the association -- enough to caption a figure, describe
it to a model, or use it as an accessible name.

The paragraph below the figure wins, because that is where Word puts a
figure caption; the one above is a fallback, since an author who typed
their own often puts it there. A caption between two figures is claimed
by the earlier one only, so the later is left uncaptioned rather than
given words about someone else's figure.

The pass is length-preserving by construction -- no block added, removed
or reordered, only an image block replaced with a copy carrying
`caption`. That is load-bearing: it runs immediately before
`insertConstructMarkers` at both block-scope entry points, and the
extent list handed alongside indexes into the same array. Applying it to
each section's own slice also means a caption never associates across a
section break, matching how an extent straddling one is dropped.

`ContentSheetImage` extends `ContentImageBlockSchema`, so it inherits
the field; both hand-authored JSON Schema fragments are updated to match
(their live-`z.toJSONSchema()` comparison test is what caught it).

Refs #1197, which asks for a fuller provenance/interpretation model --
this is the one piece of it that stands alone and needed no new concept.
@Mearman
Mearman force-pushed the feat/docx-figure-captions branch from a9432fe to 1cb7d7b Compare September 10, 2026 21:43
@Mearman
Mearman enabled auto-merge (rebase) September 10, 2026 21:44
@Mearman
Mearman merged commit fd7811e into main Sep 10, 2026
22 checks passed
@Mearman
Mearman deleted the feat/docx-figure-captions branch September 10, 2026 21:49
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 7.9.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 8.11.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants